In a computer network environment, a server may process data requests from hundreds or thousands of clients. For example, a web server may receive a request for data which, when received by the requesting client, allows the client to view a web page. The server places the request into a thread (or multiple threads) previously allocated by the server. The thread provides instructions for the flow of work required to obtain the requested data and return it to the client. Typically, the server reads the request from the server's network connection with the client in one of three ways. The read may be a “synchronous blocking read” in which the thread is blocked while waiting for the retrieval of the requested data and must complete before being released to another request. Because no thread switching is involved, synchronous blocking reads may be fast. However, because no other process may use the thread while the thread is waiting to complete, the number of network connections which may be processed at a time is limited to the number of threads allocated.
Alternatively, the read may be a “synchronous non-blocking read” in which the thread periodically attempts to read the data from the connection. Between attempts, the thread is not blocked and may perform other tasks. While efficiency may be improved relative to a synchronous blocking read, scalability (the number of network connections which may be processed at a time) remains limited.
In the third possible method, the read is an “asynchronous non-blocking read” in which the network connection is registered with a service to monitor the connection. When the requested data is ready to be read, the monitoring service calls a callback on another thread to allow the requesting client to retrieve the data. Although scalability is improved from synchronous reads, the required thread switching for every request may adversely affect performance.
Typically, another read request from the client follows data sent in response to a previous request. However, the subsequent request may follow immediately, such as when multiple requests are sent for pieces of a web page, or may follow after a considerable delay, such as when the client's user is thinking about what web page to go to next. Thus, a blocking read may be the most efficient for the former situation but a non-blocking read may be the most efficient for the latter situation.
Consequently, a need remains for improved processing of read requests from a client to a server.